from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.filters import SearchFilter
from django_filters.rest_framework import DjangoFilterBackend

from iClouds.Permissions import (
    AllPermissions,
    MyPermissions,
    BoxPermissions,
    WeChatPermissions,
    BarPermissions,
)
from iClouds.Authentication import (
    MyJWTAuthentication,
    BoxJWTAuthentication,
    WeChatJWTAuthentication,
    BarJWTAuthentication,
)
from iClouds.apidev import filter_views

from .serializers import *
from .FilterBackends import *
from . import tasks as TASKS
from mysqldb.serializers import ListDjangoFilterBackend

# Create your views here.


class TestViewSet(viewsets.ModelViewSet):
    __title__ = "测试视图"
    __doc__ = f"""
    create:\n
    <h4>会员基础信息</h4>\n
    """
    http_method_names = ["post"]
    authentication_classes = []
    permission_classes = [AllPermissions]
    serializer_class = NoneSerializer
    queryset = None

    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        # serializer.save()
        return Response({"rescode": 200, "resmsg": serializer.data})


class NewV2AllinpayReportWorkListViewSet(viewsets.ModelViewSet):
    __title__ = "工作项统计报表(异步)"
    __group__ = "报表模块"
    __info__ = {"post": "工作项统计报表(异步)"}
    __doc__ = """
    create:
    <h4>工作项统计报表(异步)</h4>
        rptype = [(1, "工作项标题"), (2, "工作项执行人")]
    """
    http_method_names = ["post"]
    authentication_classes = [
        MyJWTAuthentication,
        WeChatJWTAuthentication,
        BarJWTAuthentication,
    ]
    permission_classes = [MyPermissions | WeChatPermissions | BarPermissions]
    serializer_class = AllinpayReportWorkListSerializer
    queryset = AllinpayPlaceworkitemList.objects.all()

    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        # serializer.save()
        # print("Views:", serializer.data)
        r = TASKS.WorkListCountTask.apply_async(kwargs=serializer.data).task_id
        return Response({"rescode": 200, "resmsg": r})


class NewV2AllinpayReportInterListViewSet(viewsets.ModelViewSet):
    __title__ = "积分统计报表(异步)"
    __group__ = "报表模块"
    __info__ = {"post": "积分统计报表(异步)"}
    __doc__ = """	
    create:
    <h4>积分统计报表(异步)</h4>
        rptype = [(1, "场所统计"), (2, "员工统计")]
    """
    http_method_names = ["post"]
    authentication_classes = [
        MyJWTAuthentication,
        WeChatJWTAuthentication,
        BarJWTAuthentication,
    ]
    permission_classes = [MyPermissions | WeChatPermissions | BarPermissions]
    serializer_class = AllinpayReportInterListSerializer
    queryset = AllinpayPlaceworkitemList.objects.all()

    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        # serializer.save()
        # print("Views:", serializer.data)
        r = TASKS.InterListCountTask.apply_async(kwargs=serializer.data).task_id
        return Response({"rescode": 200, "resmsg": r})


class AllinpayReportWorkListViewSet(viewsets.ModelViewSet):
    __title__ = "工作项统计报表"
    __group__ = "报表模块"
    __info__ = {
        "get": "工作项统计报表查询",
        "post": "工作项统计报表创建",
        "put": "工作项统计报表编辑",
        "delete": "工作项统计报表移除",
    }
    __doc__ = """	list:
    <h4>工作项统计报表列表</h4>
    retrieve:
    <h4>工作项统计报表详情</h4>
    create:
    <h4>工作项统计报表创建</h4>
        choices=[(1, "工作项标题"), (2, "工作项执行人")]
    update:
    <h4>工作项统计报表编辑</h4>
    delete:
    <h4>工作项统计报表移除</h4>"""
    http_method_names = ["post"]
    authentication_classes = [
        MyJWTAuthentication,
        BoxJWTAuthentication,
        WeChatJWTAuthentication,
    ]
    permission_classes = [MyPermissions | BoxPermissions | WeChatPermissions]
    serializer_class = AllinpayReportWorkListSerializer
    queryset = AllinpayPlaceworkitemList.objects.all()

    # filter_backends = [ListDjangoFilterBackend]
    # filterset_fields = ['pid', 'intetype']
    def has_Place_Name(self, pid):
        """查询场所名"""
        try:
            r = AllinpayPlaceList.objects.get(id=pid)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def has_Staff_Name(self, sid):
        """查询员工名称"""
        try:
            r = AllinpayStaffList.objects.get(id=sid)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def create(self, request, *args, **kwargs):
        out = time.time()
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        # serializer.save()
        data = serializer.data.copy()
        rptype = data.pop("rptype")

        # 分组查询
        q = self.queryset.filter(
            currentdate__gte=data["star"],
            currentdate__lte=data["stop"],
            pid__in=data["pid"],
        )

        if rptype == 1:
            print("报表维度 工作项标题")
            x = q.values("title").annotate(c=Count("id"), pid=F("pid")).order_by("-c")
            for i in range(len(x)):
                wids = list(q.filter(title=x[i]["title"]).values_list("id", flat=True))
                x[i]["submit"] = AllinpayPlaceworkitemSubmit.objects.filter(
                    wid__in=wids
                ).count()
                x[i]["check"] = (
                    AllinpayPlaceworkitemCheck.objects.filter(wid__in=wids)
                    .values("raward")
                    .annotate(c=Count("id"))
                )
                x[i]["inter"] = AllinpayPlaceinterLog.objects.filter(
                    reqsn__in=wids
                ).aggregate(Sum("inter"))
                wsub = list(
                    AllinpayPlaceworkitemSubmit.objects.filter(
                        wid__in=wids
                    ).values_list("id", flat=True)
                )
                x[i]["unc"] = x[i]["c"] - len(wsub)
                x[i]["name"] = self.has_Place_Name(x[i]["pid"])
                for j in range(len(x[i]["check"])):
                    try:
                        n = AllinpayRawardList.objects.get(
                            id=int(x[i]["check"][j]["raward"])
                        )
                        m = AllinpayIntegralList.objects.get(id=n.intetype)
                    except BaseException as err:
                        x[i]["check"][j]["name"] = ""
                        x[i]["check"][j]["parent"] = ""
                    else:
                        x[i]["check"][j]["name"] = n.name
                        x[i]["check"][j]["parent"] = m.name
            asum = q.count()
            # try:
            #     apid = AllinpayPlaceList.objects.get(id=data["pid"])
            # except BaseException as err:
            #     pname = ""
            # else:
            #     pname = apid.name
        elif rptype == 2:
            print("报表维度 工作项执行人")
            x = q.values("onstaff").annotate(c=Count("id"), pid=F("pid")).order_by("-c")
            for i in range(len(x)):
                wids = list(
                    q.filter(onstaff=x[i]["onstaff"]).values_list("id", flat=True)
                )

                x[i]["submit"] = AllinpayPlaceworkitemSubmit.objects.filter(
                    wid__in=wids
                ).count()
                x[i]["check"] = (
                    AllinpayPlaceworkitemCheck.objects.filter(wid__in=wids)
                    .values("raward")
                    .annotate(c=Count("id"))
                )
                x[i]["inter"] = AllinpayPlaceinterLog.objects.filter(
                    reqsn__in=wids
                ).aggregate(Sum("inter"))

                wsub = list(
                    AllinpayPlaceworkitemSubmit.objects.filter(
                        wid__in=wids
                    ).values_list("id", flat=True)
                )
                x[i]["unc"] = x[i]["c"] - len(wsub)
                x[i]["staff"] = self.has_Staff_Name(x[i]["onstaff"])
                x[i]["name"] = self.has_Place_Name(x[i]["pid"])
                # try:
                #     u = AllinpayStaffList.objects.get(id=x[i]["onstaff"])
                # except BaseException as err:
                #     x[i]["name"] = ""
                # else:
                #     x[i]["name"] = u.basename

                for j in range(len(x[i]["check"])):
                    try:
                        n = AllinpayRawardList.objects.get(
                            id=int(x[i]["check"][j]["raward"])
                        )
                        m = AllinpayIntegralList.objects.get(id=n.intetype)
                    except BaseException as err:
                        x[i]["check"][j]["name"] = ""
                        x[i]["check"][j]["parent"] = ""
                    else:
                        x[i]["check"][j]["name"] = n.name
                        x[i]["check"][j]["parent"] = m.name
            asum = q.count()
            # try:
            #     apid = AllinpayPlaceList.objects.get(id=data["pid"])
            # except BaseException as err:
            #     pname = ""
            # else:
            #     pname = apid.name
        else:
            x = None
            asum = 0
            pname = ""
        return Response(
            {
                "rescode": 200,
                "resmsg": x,
                # "placeName": pname,
                "sum": asum,
                "timer": time.time() - out,
            }
        )


class AllinpayReportInterListViewSet(viewsets.ModelViewSet):
    __title__ = "积分统计报表"
    __group__ = "报表模块"
    __info__ = {
        "get": "积分统计报表查询",
        "post": "积分统计报表创建",
        "put": "积分统计报表编辑",
        "delete": "积分统计报表移除",
    }
    __doc__ = """	list:
    <h4>积分统计报表列表</h4>
    retrieve:
    <h4>积分统计报表详情</h4>
    create:
    <h4>积分统计报表创建</h4>
        choices=[(1, "场所统计"), (2, "员工统计")]
    update:
    <h4>积分统计报表编辑</h4>
    delete:
    <h4>积分统计报表移除</h4>"""
    http_method_names = ["post"]
    authentication_classes = [
        MyJWTAuthentication,
        BoxJWTAuthentication,
        WeChatJWTAuthentication,
    ]
    permission_classes = [MyPermissions | BoxPermissions | WeChatPermissions]
    serializer_class = AllinpayReportInterListSerializer
    queryset = AllinpayPlaceworkitemList.objects.all()

    # filter_backends = [ListDjangoFilterBackend]
    # filterset_fields = ['pid', 'intetype']
    def has_Place_Name(self, pid):
        """查询场所名"""
        try:
            r = AllinpayPlaceList.objects.get(id=pid)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def has_Staff_Name(self, sid):
        """查询员工名称"""
        try:
            r = AllinpayStaffList.objects.get(id=sid)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def create(self, request, *args, **kwargs):
        out = time.time()
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        # serializer.save()
        data = serializer.data.copy()
        rptype = data.pop("rptype")
        print(data)
        q = self.queryset.filter(
            currentdate__gte=data["star"],
            currentdate__lte=data["stop"],
            pid__in=data["pid"],
        )
        if rptype == 1:
            print("报表维度 场所统计")
            x = q.values("pid").annotate(c=Count("id")).order_by("-c")
            for i in range(len(x)):
                wids = list(q.filter(pid=x[i]["pid"]).values_list("id", flat=True))
                x[i]["submit"] = AllinpayPlaceworkitemSubmit.objects.filter(
                    wid__in=wids
                ).count()
                x[i]["check"] = (
                    AllinpayPlaceworkitemCheck.objects.filter(wid__in=wids)
                    .values("raward")
                    .annotate(c=Count("id"))
                )
                x[i]["inter"] = AllinpayPlaceinterLog.objects.filter(
                    reqsn__in=wids
                ).aggregate(Sum("inter"))
                wsub = list(
                    AllinpayPlaceworkitemSubmit.objects.filter(
                        wid__in=wids
                    ).values_list("id", flat=True)
                )
                x[i]["unc"] = x[i]["c"] - len(wsub)
                x[i]["name"] = self.has_Place_Name(x[i]["pid"])
                for j in range(len(x[i]["check"])):
                    try:
                        n = AllinpayRawardList.objects.get(
                            id=int(x[i]["check"][j]["raward"])
                        )
                        m = AllinpayIntegralList.objects.get(id=n.intetype)
                    except BaseException as err:
                        x[i]["check"][j]["name"] = ""
                        x[i]["check"][j]["parent"] = ""
                    else:
                        x[i]["check"][j]["name"] = n.name
                        x[i]["check"][j]["parent"] = m.name
            print(x)
        elif rptype == 2:
            print("报表维度 员工统计")
            x = q.values("onstaff").annotate(c=Count("id")).order_by("-c")
            for i in range(len(x)):
                wids = list(
                    q.filter(onstaff=x[i]["onstaff"]).values_list("id", flat=True)
                )
                x[i]["submit"] = AllinpayPlaceworkitemSubmit.objects.filter(
                    wid__in=wids
                ).count()
                x[i]["check"] = (
                    AllinpayPlaceworkitemCheck.objects.filter(wid__in=wids)
                    .values("raward")
                    .annotate(c=Count("id"))
                )
                x[i]["inter"] = AllinpayPlaceinterLog.objects.filter(
                    reqsn__in=wids
                ).aggregate(Sum("inter"))
                wsub = list(
                    AllinpayPlaceworkitemSubmit.objects.filter(
                        wid__in=wids
                    ).values_list("id", flat=True)
                )
                x[i]["unc"] = x[i]["c"] - len(wsub)
                x[i]["name"] = self.has_Staff_Name(x[i]["onstaff"])
                for j in range(len(x[i]["check"])):
                    try:
                        n = AllinpayRawardList.objects.get(
                            id=int(x[i]["check"][j]["raward"])
                        )
                        m = AllinpayIntegralList.objects.get(id=n.intetype)
                    except BaseException as err:
                        x[i]["check"][j]["name"] = ""
                        x[i]["check"][j]["parent"] = ""
                    else:
                        x[i]["check"][j]["name"] = n.name
                        x[i]["check"][j]["parent"] = m.name
            print(x)
        else:
            x = None
        return Response({"rescode": 200, "resmsg": x})


# ==============================================================
# 凡商商品订单
# ==============================================================
class FsygWorksGroupsListViewSet(viewsets.ModelViewSet):
    __title__ = "查询终端分组"
    __group__ = "报表模块"
    __info__ = {"post": "查询终端分组"}
    __doc__ = """	
    create:
    <h4>查询终端分组</h4>
    """
    http_method_names = ["post"]
    authentication_classes = (
        [
            MyJWTAuthentication,
            BoxJWTAuthentication,
            WeChatJWTAuthentication,
        ]
        if not settings.DEBUG
        else []
    )
    permission_classes = (
        [MyPermissions | BoxPermissions | WeChatPermissions]
        if not settings.DEBUG
        else [AllPermissions]
    )
    serializer_class = PlaceSerializer
    queryset = FsygPchardList.objects.all()

    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        # serializer.save()
        r = (
            FsygPchardList.objects.filter(pid=serializer.data.get("pid"))
            .values_list("group", flat=True)
            .distinct()
        )
        return Response({"rescode": 200, "resmsg": r})


class FsygPchardListViewSet(viewsets.ModelViewSet):
    __title__ = "终端区域"
    __group__ = "报表模块"
    __info__ = {"get": "查询终端区域列表", "post": "创建", "put": "编辑", "delete": "移除"}
    __doc__ = """	
    list:
    <h4>终端区域列表</h4>
    retrieve:
    <h4>终端区域详情</h4>
    """
    http_method_names = ["get"]
    authentication_classes = (
        [
            MyJWTAuthentication,
            BoxJWTAuthentication,
            WeChatJWTAuthentication,
        ]
        if not settings.DEBUG
        else []
    )
    permission_classes = (
        [MyPermissions | BoxPermissions | WeChatPermissions]
        if not settings.DEBUG
        else [AllPermissions]
    )
    serializer_class = FsygPchardListSerializer
    queryset = FsygPchardList.objects.all()

    filter_backends = [ListDjangoFilterBackend]
    filterset_fields = ["pid", "group"]

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response({"rescode": 200, "resmsg": serializer.data})

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({"rescode": 200, "resmsg": serializer.data})


class FsygShopreqsnListViewSet(viewsets.ModelViewSet):
    __title__ = "商品订单列表"
    __group__ = "报表模块"
    __info__ = {"get": "查询商品订单列表"}
    __doc__ = """	
    list:
    <h4>查询商品订单列表</h4>
    retrieve:
    <h4>查询商品订单详情</h4>
    """
    http_method_names = ["get"]
    authentication_classes = (
        [
            MyJWTAuthentication,
            BoxJWTAuthentication,
            WeChatJWTAuthentication,
            BarJWTAuthentication,
        ]
        if not settings.DEBUG
        else []
    )
    permission_classes = (
        [MyPermissions | BoxPermissions | WeChatPermissions | BarPermissions]
        if not settings.DEBUG
        else [AllPermissions]
    )
    serializer_class = FsygShopreqsnListSerializer
    queryset = FsygShopreqsnList.objects.all()

    filter_backends = [ListDjangoFilterBackend, SearchFilter]
    filterset_class = ReqsnFilter
    search_fields = ["wb_id", "reqsn", "machine_no"]

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response({"rescode": 200, "resmsg": serializer.data})

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({"rescode": 200, "resmsg": serializer.data})


class FsygMemberListViewSet(viewsets.ModelViewSet):
    __title__ = "场所会员列表"
    __group__ = "报表模块"
    __info__ = {"get": "查询场所会员列表"}
    __doc__ = """	list:
    <h4>场所会员列表</h4>
    retrieve:
    <h4>场所会员详情</h4>
    """
    http_method_names = ["get"]
    authentication_classes = (
        [
            MyJWTAuthentication,
            BoxJWTAuthentication,
            WeChatJWTAuthentication,
        ]
        if not settings.DEBUG
        else []
    )
    permission_classes = (
        [MyPermissions | BoxPermissions | WeChatPermissions]
        if not settings.DEBUG
        else [AllPermissions]
    )
    serializer_class = FsygMemberListSerializer
    queryset = FsygMemberList.objects.all()

    filter_backends = [ListDjangoFilterBackend]
    filterset_fields = ["wb_id", "level"]

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response({"rescode": 200, "resmsg": serializer.data})

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({"rescode": 200, "resmsg": serializer.data})


class ReportTermLimitViewSet(viewsets.ModelViewSet):
    __title__ = "商品销售同比统计"
    __group__ = "报表模块"
    __info__ = {"post": "商品销售同比统计"}
    __doc__ = """
    create:
    <h4>商品销售同比统计</h4>
        "resmsg":  {
        "name":  "同步数据",
        "data":  [
            {
            "name":  "aaaa", 场所终端区域名称
                # 订单金额 (分)
            "now_money":  1200,
            "last_money":  0,
            # 订单数量
            "now_count":  1,
            "last_count":  0,
            # 商品数量
            "now_limit":  2,
            "last_limit":  0,
            # 单品数量
            "now_goods":  0,
            "last_goods":  0,
            # 组合数量
            "now_combo":  0,
            "last_combo":  0,
            # 会员统计
            "member":  [
                {
                "name":  "\u4e34\u65f6\u5361", # 会员等级
                "now_money":  0,
                "last_money":  0
                },
            ],
            # 统计团队
            "teamer":  [
                {
                "name":  "\u6d4b\u8bd5\u56e2\u961f01",
                "now_money":  0,
                "last_money":  0
                }
            ],
            # 统计个人
            "staffer":  [
                {
                "name":  "",
                "now_money":  0,
                "last_money":  0
                }
            ]
            }
        ],
        # 商品榜
        "shop":  [
            {
            "product_name":  "\u5eb7\u5e08\u5085\u8309\u8389\u6e05\u83361L",
            "tongji":  1.0
            },
            {
            "product_name":  "\u8109\u52a8\u9752\u67e0600ML",
            "tongji":  1.0
            }
        ],
        # 员工榜
        "staff":  []
        }
        
    """
    http_method_names = ["post"]
    authentication_classes = [
        MyJWTAuthentication,
        BoxJWTAuthentication,
        WeChatJWTAuthentication,
        BarJWTAuthentication,
    ]
    permission_classes = [
        MyPermissions | BoxPermissions | WeChatPermissions | BarPermissions
    ]

    serializer_class = ReportTermLimitSerializer
    queryset = None

    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        # serializer.save()
        # 初始化数据
        data = serializer.data.copy()
        print(data)
        term = ["", "", "", 0]
        if data["week"]:
            thday = date(data["year"], 1, 1)
            tkday = thday + timedelta(days=7 * data["week"])
            term[0] = tkday
            term[1] = tkday + timedelta(days=7)
            term[2] = "w"
            term[3] = data.get("pid")
        elif data["day"]:
            thday = date(data["year"], data["month"], data["day"])
            term[0] = thday
            term[1] = thday + timedelta(days=1)
            term[2] = "d"
            term[3] = data.get("pid")
        elif data["month"]:
            y, m = data["year"], data["month"] + 1
            by = y if m < 13 else y + 1
            bm = m if m < 13 else m - 12
            term[0] = date(data["year"], data["month"], 1)
            term[1] = date(by, bm, 1)
            term[2] = "m"
            term[3] = data.get("pid")
        else:
            term = None

        # print(type(term[0]), type(term[1]))
        # 异步请求
        if term:
            r = TASKS.TasksReportTermLimit.apply_async(
                args=(term[0], term[1], term[2], term[3])
            )

            return Response(
                {"rescode": 200, "resmsg": serializer.data, "task_id": r.task_id}
            )
        else:
            return Response({"rescode": 204, "resmsg": serializer.data})


# r = TASKS.TasksReportTermLimit.apply_async(
#     args=("2023-08-01", "2023-09-01", "m", 1000001)
# )
# 检查视图
from iClouds.apidev import filter_views

filter_views(globals())
